Git Internals 读书笔记

Git Internals 读书笔记。

Git Internals

Git Object Types

Git有四种对象类型,分别是BlobTreeCommitTag,都存储在对象数据库里,都是通过Zlib压缩过的,使用SHA-1值(内容的哈希值)来表示。

使用书上的例子:

working

Blob

Git中,文件的内容是作为Blob进行存储的。

blob

对于具有相同内容的不同文件,只存储一份。

BLOb

Tree

Tree就对应着目录。

tree

tree存储该目录下的目录和文件的信息(mode,type,name,sha)。

tree

Commit

commit对象指向一个tree对象,然后额外保存了作者,提交者,提交信息和上次提交这些信息。

commit

第一次提交

commit1

第二次提交

在第二次提交中,就有了parent这一信息,指向上一次的提交对象。

commit2

Tag

Tag对象指向一个特定的commit对象,保存objecttypetagtaggermessage信息。type一般就是commitobject就是这个commitSHA-1值。

tag

Git Data Model

The Model

model

带颜色是不可变对象。

Example

目录文件如下

|-- init.rb
 -- lib
    | -- base
        | -- base_include.rb
     -- my_plugin.rb

第一次提交后,Git Model如下

model

branch指向最近的一次提交,HEAD指向当前的branch

现在修改lib/base/base_include.rb文件,然后提交,并创建一个tag

修改了文件,其父目录以及父目录的父目录直到最顶层目录的内容都被修改了,就会产生新的对象。对于没有改变的文件和目录则不会产生新对象。

model

现在修改init.rb文件,然后提交。

由于只修改了init.rb文件,其他的子目录并没有变化,所以就不会产生其他的新对象。如下图所示。

model

这样的一种模型,我们可以通过当前的HEAD得到所有的历史文件。

Traversal

当进行checkout的时候,通过查看.git/refs目录下的branchtagremote,将当前的working directory的内容切换到指定的commit的内容。

traverse

Branching and Merging

Git中,创建分支,切换分支是非常容易的,就是新建一个文件和写几个字符的事。

在这个例子中,创建一个experiment分支,然后对masterexperiment分支分别提交。现在就是下面这个样子。

branch

experiment分支合并到master分支后就像下面这样。

branch

Remotes

远程分支的名字类似与这样origin/master表示远程仓库originmaster分支。远程仓库的名字origin是可以自定义的,不一定就是origin

下面表示有三个分支,两个远程仓库分支ideamaster,一个本地分支。

remote

对这三个分支进行合并,就成了下面这个样子。

remtoe

Rebasing

在多人合作开发时,将别人的代码合并到自己本地时,就会产生下面所示的情况。

rebase

C2C4C5这些并没有什么实质的内容,只是进行合并产生的提交。当有大量的这些提交后,我们的提交历史就会变得不清晰。这时,我们可以使用rebase

使用rebase的效果和merge的效果如下所示。

1是rebase产生的提交历史。
2是merge产生的提交历史。

rebase

rebase只在本地分支上使用,不要在公共的分支上进行rebase!